package com.example.micro_property_springboot.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.micro_property_springboot.pojo.AssetCheckDiff;
import com.example.micro_property_springboot.pojo.DTO.request.AssetCheckDiffHandleRequest;
import com.example.micro_property_springboot.pojo.VO.PageResult;
import com.example.micro_property_springboot.pojo.VO.Result;
import com.example.micro_property_springboot.service.AssetCheckDiffService;
import com.example.micro_property_springboot.service.AssetCheckPlanService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.List;

/**
 * 资产盘点差异管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/check-plan/{planId}/diffs")
@Tag(name = "盘点差异管理", description = "资产盘点差异相关操作")
public class AssetCheckDiffController {

    @Autowired
    private AssetCheckDiffService assetCheckDiffService;

    @Autowired
    private AssetCheckPlanService assetCheckPlanService;

    /**
     * 分页查询盘点差异列表
     */
    @GetMapping
    @Operation(summary = "分页查询盘点差异列表", description = "根据盘点计划ID分页查询资产盘点差异列表")
    public Result<PageResult<AssetCheckDiff>> getAssetCheckDiffs(
            @PathVariable Long planId,
            @RequestParam Integer pageNum,
            @RequestParam Integer pageSize,
            @RequestParam(required = false) String diffType) {
        log.info("分页查询盘点差异列表，计划ID：{}，页码：{}，页大小：{}，差异类型：{}",
                planId, pageNum, pageSize, diffType);

        try {
            // 设置分页参数
            Page<AssetCheckDiff> page = new Page<>(pageNum, pageSize);

            // 设置条件查询
            QueryWrapper<AssetCheckDiff> wrapper = new QueryWrapper<>();
            wrapper.eq("plan_id", planId);
            if (diffType != null && !diffType.isEmpty()) {
                wrapper.eq("diff_type", diffType);
            }
            wrapper.orderByDesc("create_time");

            // 执行查询
            Page<AssetCheckDiff> diffPage = assetCheckDiffService.page(page, wrapper);

            // 转换为自定义的PageResult
            PageResult<AssetCheckDiff> pageResult = new PageResult<>();
            pageResult.setTotal(diffPage.getTotal());
            pageResult.setRows(diffPage.getRecords());

            log.info("成功获取{}个盘点差异，计划ID：{}", diffPage.getRecords().size(), planId);
            return Result.success("查询成功", pageResult);
        } catch (Exception e) {
            log.error("分页查询盘点差异列表失败，计划ID：{}，错误信息：{}", planId, e.getMessage(), e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }

    /**
     * 获取盘点差异详情
     */
    @GetMapping("/{diffId}")
    @Operation(summary = "获取盘点差异详情", description = "根据差异ID获取资产盘点差异详情")
    public Result<AssetCheckDiff> getAssetCheckDiffById(
            @PathVariable Long planId,
            @PathVariable Long diffId) {
        log.info("获取盘点差异详情，计划ID：{}，差异ID：{}", planId, diffId);

        try {
            AssetCheckDiff diff = assetCheckDiffService.getById(diffId);
            if (diff == null) {
                log.warn("盘点差异不存在，差异ID：{}", diffId);
                return Result.error("盘点差异不存在");
            }

            // 验证差异是否属于指定的盘点计划
            if (!diff.getPlanId().equals(planId)) {
                log.warn("差异不属于指定的盘点计划，差异ID：{}，计划ID：{}，差异的计划ID：{}",
                        diffId, planId, diff.getPlanId());
                return Result.error("差异不属于指定的盘点计划");
            }

            log.info("成功获取盘点差异详情，差异ID：{}", diffId);
            return Result.success("查询成功", diff);
        } catch (Exception e) {
            log.error("获取盘点差异详情失败，差异ID：{}，错误信息：{}", diffId, e.getMessage(), e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }

    /**
     * 处理盘点差异
     */
    @PostMapping("/{diffId}/handle")
    @Operation(summary = "处理盘点差异", description = "根据差异ID处理资产盘点差异")
    public Result<AssetCheckDiff> handleAssetCheckDiff(
            @PathVariable Long planId,
            @PathVariable Long diffId,
            @Valid @RequestBody AssetCheckDiffHandleRequest request) {
        log.info("处理盘点差异，计划ID：{}，差异ID：{}，请求参数：{}", planId, diffId, request);

        try {
            // TODO: 获取当前登录用户ID（实际应从认证信息中获取）
            Long userId = getCurrentUserId();

            AssetCheckDiff diff = assetCheckDiffService.handleAssetCheckDiff(diffId, request, userId);
            log.info("成功处理盘点差异，差异ID：{}", diffId);
            return Result.success("处理成功", diff);
        } catch (RuntimeException e) {
            log.error("处理盘点差异失败，差异ID：{}，错误信息：{}", diffId, e.getMessage());
            return Result.error("处理失败：" + e.getMessage());
        }
    }

    /**
     * 确认盘点差异
     */
    @PostMapping("/confirm")
    @Operation(summary = "确认盘点差异", description = "根据盘点计划ID确认所有资产盘点差异")
    public Result<Void> confirmAssetCheckDiffs(@PathVariable Long planId) {
        log.info("确认盘点差异，计划ID：{}", planId);

        try {
            // TODO: 获取当前登录用户ID（实际应从认证信息中获取）
            Long userId = getCurrentUserId();

            assetCheckDiffService.confirmAssetCheckDiffs(planId, userId);
            log.info("成功确认盘点差异，计划ID：{}", planId);
            return Result.success("确认成功");
        } catch (RuntimeException e) {
            log.error("确认盘点差异失败，计划ID：{}，错误信息：{}", planId, e.getMessage());
            return Result.error("确认失败：" + e.getMessage());
        }
    }

    /**
     * 生成盘点差异
     */
    @PostMapping("/generate")
    @Operation(summary = "生成盘点差异", description = "根据盘点计划ID生成资产盘点差异")
    public Result<Void> generateCheckDiffs(@PathVariable Long planId) {
        log.info("生成盘点差异，计划ID：{}", planId);

        try {
            assetCheckDiffService.generateCheckDiffs(planId);
            log.info("成功生成盘点差异，计划ID：{}", planId);
            return Result.success("生成成功");
        } catch (RuntimeException e) {
            log.error("生成盘点差异失败，计划ID：{}，错误信息：{}", planId, e.getMessage());
            return Result.error("生成失败：" + e.getMessage());
        }
    }

    /**
     * 删除盘点差异
     */
    @DeleteMapping("/{diffId}")
    @Operation(summary = "删除盘点差异", description = "根据差异ID删除资产盘点差异")
    public Result<Void> deleteAssetCheckDiff(
            @PathVariable Long planId,
            @PathVariable Long diffId) {
        log.info("删除盘点差异，计划ID：{}，差异ID：{}", planId, diffId);

        try {
            AssetCheckDiff diff = assetCheckDiffService.getById(diffId);
            if (diff == null) {
                log.warn("盘点差异不存在，差异ID：{}", diffId);
                return Result.error("盘点差异不存在");
            }

            // 验证差异是否属于指定的盘点计划
            if (!diff.getPlanId().equals(planId)) {
                log.warn("差异不属于指定的盘点计划，差异ID：{}，计划ID：{}，差异的计划ID：{}",
                        diffId, planId, diff.getPlanId());
                return Result.error("差异不属于指定的盘点计划");
            }

            boolean result = assetCheckDiffService.removeById(diffId);
            if (result) {
                log.info("成功删除盘点差异，差异ID：{}", diffId);
                return Result.success("删除成功");
            } else {
                log.error("删除盘点差异失败，差异ID：{}", diffId);
                return Result.error("删除失败");
            }
        } catch (Exception e) {
            log.error("删除盘点差异异常，差异ID：{}，错误信息：{}", diffId, e.getMessage(), e);
            return Result.error("删除失败：" + e.getMessage());
        }
    }

    /**
     * 获取当前登录用户ID
     * TODO: 实际实现应从Spring Security认证信息中获取
     * @return 当前用户ID
     */
    private Long getCurrentUserId() {
        // 这里仅为示例，实际需要从认证信息中获取
        // 例如：SecurityContextHolder.getContext().getAuthentication().getPrincipal()
        return 1L;
    }
}
